﻿namespace PrismEx.Events
{
    using System.Collections.Concurrent;
    using System.Linq;

    using Microsoft.Practices.Prism.Events;

    public class QueuedEvent<TEventType> : CompositePresentationEvent<TEventType>
        where TEventType : QueuedEvent<TEventType>
    {
        private ConcurrentQueue<TEventType> queue = new ConcurrentQueue<TEventType>();

        public QueuedEvent()
        {
        }

        public override void Publish(TEventType payload)
        {
            if (!this.Subscriptions.Any())
            {
                queue.Enqueue(payload);
            }

            base.Publish(payload);
        }

        public override SubscriptionToken Subscribe(System.Action<TEventType> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, System.Predicate<TEventType> filter)
        {
            var subscriptionToken = base.Subscribe(action, threadOption, keepSubscriberReferenceAlive, filter);
            
            TEventType queuedEvent;

            while (queue.TryDequeue(out queuedEvent))
            {
                base.Publish(queuedEvent);
            }

            return subscriptionToken;
        }
    }
}